#ifndef _SHAPE_H_
#define _SHAPE_H_

#include "Shapes/ShapesUI.h"
#include "vecmath/Vector3.h"
#include "vecmath/Point3.h"
#include "UIInterface.h"
#include <vector>
#include <cmath>

#include "../intersection/HitRecord.h"
#include "../intersection/rootfinder.h"

struct Triangle {
public:
	Triangle(Point3 _p1, Vector3 _v1, Point3 _p2, Vector3 _v2, Point3 _p3, Vector3 _v3);
	Point3 p1, p2, p3;
	Vector3 v1, v2, v3, normal;
	void draw();

	HitRecord intersect(const Point3& origin, const Vector3& ray);
	Triangle& operator=(const Triangle& a);
};

class Shape {
public:
	Shape(){listName=0;};
	Shape(int _tessel1, int _tessel2) : tessel1(_tessel1), tessel2(_tessel2){listName=0;};
	~Shape(){if(listName!=0)glDeleteLists(listName, 1);};
	
	virtual HitRecord intersect(const Point3& origin, const Vector3& ray);
	void draw();
protected:
	int tessel1;
	int tessel2;
	std::vector<Triangle> triangles;
	GLuint listName;
	void buildDrawList();
};

class Cube : public Shape {
public:
	Cube(int _tessel1=1, int _tessel2=1);
	HitRecord intersect(const Point3& origin, const Vector3& ray);
};

class Cylinder : public Shape {
public:
	Cylinder(int _tessel1=20, int _tessel2=1);
	HitRecord intersect(const Point3& origin, const Vector3& ray);
};

class Cone : public Shape {
public:
	Cone(int _tessel1=20, int _tessel2=1);
	HitRecord intersect(const Point3& origin, const Vector3& ray);
};

class Sphere : public Shape {
public:
	Sphere(int _tessel1=5, int _tessel2=5);
	HitRecord intersect(const Point3& origin, const Vector3& ray);
private:
	void splitTriangle(Triangle t, int times);
};

class Torus : public Shape {
public:
	Torus(int _tessel1, int _tessel2);
	//HitRecord intersect(const Point3& origin, const Vector3& ray);
};

class Corkscrew : public Shape {
public:
	Corkscrew(int _tessel1, int _tessel2);
	//HitRecord intersect(const Point3& origin, const Vector3& ray);
};

class Toroid : public Shape {
public:
	Toroid(int _tessel1, int _tessel2);
	//HitRecord intersect(const Point3& origin, const Vector3& ray);
};

#endif